package cn.virens.common.apifox;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.virens.common.apifox.build.ApiFoxCollection;
import cn.virens.common.exception.APIException;
import cn.virens.common.utils.Assert;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

@SuppressWarnings("serial")
public class ApifoxTree extends ConcurrentHashMap<String, ApiFoxCollection> {
    private final static String ROOT = "ROOT";

    /**
     * 按组添加一个API
     */
    public boolean addApi(String groupKey, ApiFoxCollection api) {
        return getGroup(group0(groupKey)).getItems().add(api);
    }

    /**
     * 安全构造分组路径
     */
    private static String group0(String groupKey) throws APIException {
        String str = FileUtil.normalize(group1(groupKey));

        str = StrUtil.removeSuffix(str, "/");
        str = StrUtil.removePrefix(str, "/");

        return str;
    }

    /**
     * 层级前拼接ROOT
     */
    private static String group1(String groupKey) throws APIException {
        if (groupKey != null && !groupKey.isEmpty()) {
            return ROOT + "/" + groupKey;
        } else {
            return ROOT;
        }
    }

    /**
     * 获取当前目录
     */
    private ApiFoxCollection getGroup(String groupKey) throws APIException {
        ApiFoxCollection collection = get(Assert.isEmpty(groupKey));
        if (collection == null || collection.getItems() == null) {
            ApiFoxCollection temp = new ApiFoxCollection();
            temp.setItems(new ArrayList<>());
            temp.setName(toName(groupKey));

            return save(groupKey, temp);
        }

        return collection;
    }

    /**
     * 保存当前层级（建立完整层级关系）
     */
    private ApiFoxCollection save(String groupKey, ApiFoxCollection collection) {
        if (groupKey != null && !StrUtil.equals(groupKey, ROOT)) {
            getParent(groupKey).getItems().add(collection);
        }

        put(groupKey, collection);

        return collection;
    }

    /**
     * 获取上级目录（根据当前层级标识分割获取上级信息）
     */
    private ApiFoxCollection getParent(String groupKey) throws APIException {
        return getGroup(StrUtil.subBefore(groupKey, '/', true));
    }

    /**
     * 根据层级标识获取当前对应的名称
     */
    private static String toName(String groupKey) throws APIException {
        return StrUtil.subAfter(groupKey, '/', true);
    }

    /**
     * 返回根节点下的所有接口
     */
    public List<ApiFoxCollection> toList() throws APIException {
        return Optional.ofNullable(get(ROOT)).map(root -> {
            return root != null ? root.getItems() : null;
        }).orElseGet(Collections::emptyList);
    }
}
